1 Introduction

2 Executive Summary

2.1 Setup

library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ────────────────────────────── tidyverse 1.3.2 ──
✔ ggplot2 3.3.6      ✔ purrr   0.3.5 
✔ tibble  3.1.8      ✔ dplyr   1.0.10
✔ tidyr   1.2.1      ✔ stringr 1.4.1 
✔ readr   2.1.3      ✔ forcats 0.5.2 
── Conflicts ───────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
library(readxl)
url_summary <- "https://wir2022.wid.world/www-site/uploads/2022/03/WIR2022TablesFigures-Summary.xlsx"
download.file(url = url_summary, destfile = "data/WIR2022TablesFigures-Summary.xlsx") 
summary_sheets <- excel_sheets("data/WIR2022TablesFigures-Summary.xlsx")
summary_sheets
 [1] "Index"     "F1"        "F2"        "F3"        "F4"       
 [6] "F5."       "F6"        "F7"        "F8"        "F9"       
[11] "F10"       "F11"       "F12"       "F13"       "F14"      
[16] "F15"       "T1"        "data-F1"   "data-F2"   "data-F3"  
[21] "data-F4"   "data-F5"   "data-F6"   "data-F7"   "data-F8"  
[26] "data-F9"   "data-F10"  "data-F11"  "data-F12"  "data-F13."
[31] "data-F14." "data-F15" 
  • Note that some of the sheet names contain a period.
df_index <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "Index")
df_index
  • The list of the titles of the tables and the figures.

2.2 Data and Charts

2.2.1 F1: Global income and wealth inequality, 2021

df_f1 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F1")
New names:
• `` -> `...1`
df_f1
df_f1 %>% select(cat = ...1, 2:4) %>%
  pivot_longer(2:4, names_to = "level", values_to = "value") %>%
  ggplot(aes(x = cat, y = value, fill = level)) +
  geom_col(position = "dodge") + 
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(title = "Figure 1. Global income and wealth inequality, 2021",
       x = "", y = "Share of total income or wealth", fill = "")

Interpretation: The global bottom 50% captures 8.5% of total income measured at Purchasing Power Parity (PPP). The global bottom 50% owns 2% of wealth (at Purchasing Power Parity). The global top 10% owns 76% of total Household wealth and captures 52% of total income in 2021. Note that top wealth holders are not necessarily top income holders. Incomes are measured after the operation of pension and unemployment systems and before taxes and transfers.
Sources and series: wir2022.wid.world/methodology.

2.2.2 F2: The poorest half lags behind: Bottom 50%, middle 40% and top 10% income shares across the world in 2021

df_f2 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F2")
df_f2
df_f2 %>% pivot_longer(3:5, names_to = "level", values_to = "value") %>%
  ggplot(aes(x = iso, y = value, fill = level)) +
  geom_col(position = "dodge") + 
  scale_x_discrete(labels = function(x) stringr::str_wrap(x, width = 10)) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(title = "Figure 2. The poorest half lags behind", 
       subtitle = "Bottom 50%, middle 40% and top 10% income shares across the world in 2021",
       x = "", y = "Share of national income (%)", fill = "")

Interpretation: In Latin America, the top 10% captures 55% of national income, compared to 36% in Europe. Income is measured after pension and unemployment contributions and benefits paid and received by individuals but before income taxes and other transfers.
Sources and series: www.wir2022.wid.world/methodology.

df_f2 %>% pivot_longer(3:5, names_to = "level", values_to = "value") %>%
  ggplot(aes(x = iso, y = value, fill = level)) +
  geom_col(position = "dodge") + 
  theme(axis.text.x = element_text(angle = 30, vjust = 1, hjust=1)) + 
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(title = "Figure 2. The poorest half lags behind", 
       subtitle = "Bottom 50%, middle 40% and top 10% income shares across the world in 2021",
       x = "", y = "Share of national income (%)", fill = "")

2.2.3 F3: Top 10/Bottom 50 income gaps across the world, 2021

df_f3 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F3")
df_f3

2.2.4 F4: The extreme concentration of capital: wealth inequality across the world, 2021

df_f4 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F4")
df_f4
  • Wrap long label: scale_x_discrete(labels = function(x) stringr::str_wrap(x, width = 10))
  • Per Cent: scale_y_continuous(labels = scales::percent_format(accuracy = 1))
df_f4 %>% pivot_longer(3:5, names_to = "level", values_to = "value") %>%
  ggplot(aes(x = iso, y = value, fill = level)) +
  geom_col(position = "dodge") + 
  scale_x_discrete(labels = function(x) stringr::str_wrap(x, width = 10)) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(title = "Figure 4. The extreme concentration of capital:", 
       subtitle = "wealth inequality across the world, 2021",
       x = "", y = "Share of national wealth (%)", fill = "")

Interpretation: The Top 10% in Latin America captures 77% of total household wealth, versus 22% for the Middle 40% and 1% for the Bottom 50%. In Europe, the Top 10% owns 58% of total wealth, versus 38% for the Middle 40% and 4% for the Bottom 50%.
Sources and series: wir2022.wid.world/methodology.

2.2.5 F5: Global income inequality: T10/B50 ratio, 1820-2020

df_f5 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F5")
df_f5

Use span Argument to Fit to Data

  • y-axis: lims(y = c(10,70))
  • stringr::str_wrap("long text", width = size)
  • annotate with size = fontsize
df_f5 %>% select(year = y, ratio = t10b50) %>%
  ggplot(aes(x = year, y = ratio)) + 
  lims(y = c(10,70)) + 
  stat_smooth(span = 0.25, se = FALSE) + 
  scale_x_continuous(breaks = round(seq(1820, 2020, by = 20),1)) + 
  labs(title = "Figure 5. Global income inequality:T10/B50 ratio, 1820-2020", 
       x = "", y = stringr::str_wrap("Ratio of top 10% average income to bottom 50% average income", width = 35)) +
  annotate("text", x = 1840, y = 32, label = stringr::str_wrap("1820: average income of the global top 10% is 18x higher than average income of the bottom 50%", width = 20), size = 3) + 
  annotate("text", x = 1910, y = 49, label = stringr::str_wrap("1910: average income of the global top 10% is 41x higher than average income of the bottom 50%", width = 20), size = 3) +
    annotate("text", x = 1980, y = 60, label = stringr::str_wrap("1980: average income of the global top 10% is 53x higher than average income of the bottom 50%", width = 20), size = 3) +
    annotate("text", x = 2010, y = 32, label = stringr::str_wrap("2020: average income of the global top 10% is 38x higher than average income of the bottom 50%", width = 20), size = 3)
`geom_smooth()` using method = 'loess' and formula 'y ~ x'

Interpretation. Global inequality, as measured by the ratio T10/B50 between the average income of the top 10% and the average income of the bottom 50%, more than doubled between between 1820 and 1910, from less than 20 to about 40, and stabilized around 40 between 1910 and 2020. It is too early to say whether the decline in global inequality observed since 2008 will continue. Income is measured per capita after pension and unemployement insurance transfers and before income and wealth taxes.
Sources and series: wir2022.wid.world/lmethodology and Chancel and Piketty (2021)..

  • ggforce::geom_mark_rect will add annotation in a box.

Line Plot and LOESS

df_f5 %>% select(year = y, ratio = t10b50) %>%
  ggplot(aes(x = year, y = ratio)) +
  geom_line() +
  geom_smooth(method = "loess", se = FALSE) + 
  labs(title = "Figure 5. Global income inequality:", 
       subtitle = "T10/B50 ratio, 1820-2020",
       x = "", y = "Ratio of top 10% average income to bottom 50% average income")
`geom_smooth()` using formula 'y ~ x'

GAM Smoothing with 24 Points

df_f5 %>% select(year = y, ratio = t10b50) %>%
  ggplot(aes(x = year, y = ratio)) +
  stat_smooth(method = "gam", formula = y ~ s(x, k = 24), se = FALSE) + 
  scale_x_continuous(breaks = round(seq(min(df_f5$y), max(df_f5$y), by = 20),1)) + 
  labs(title = "Figure 5. Global income inequality:T10/B50 ratio, 1820-2020", 
       x = "", y = stringr::str_wrap("Ratio of top 10% average income to bottom 50% average income", width = 35))

Polynomial Approximation of Degree 6

df_f5 %>% select(year = y, ratio = t10b50) %>%
  ggplot(aes(x = year, y = ratio)) +
  geom_point() +
  geom_smooth(method = "lm", formula = y ~ poly(x, 6), se = FALSE) + 
  labs(title = "Figure 5. Global income inequality:", 
       subtitle = "T10/B50 ratio, 1820-2020",
       x = "", y = "Ratio of top 10% average income to bottom 50% average income")

2.2.6 F6: Global income inequality: Between vs. Within country inequality (Theil index), 1820-2020

df_f6 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F6")
New names:
• `` -> `...1`
df_f6
  • rev(scales::hue_pal()(2)): reversing the order of colors to fill.
df_f6 %>% select(year = "...1", 2:3) %>%
  pivot_longer(cols = 2:3, names_to = "type", values_to = "value") %>%
  mutate(types = factor(type, levels = c("Within-country inequality", "Between-country inequality"))) %>%
  ggplot(aes(x = year, y = value, fill = types)) +
  geom_area() +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  scale_x_continuous(breaks = round(seq(1820, 2020, by = 20),1)) + 
  scale_fill_manual(values=rev(scales::hue_pal()(2)), labels = function(x) str_wrap(x, width = 15)) +
  labs(title = "Figure 6. Global income inequality:", 
       subtitle = "Between vs. within country inequality (Theil index), 1820-2020",
       x = "", y = "Share of global inequality (% of total Theil index)", fill = "") + 
  annotate("text", x = 1850, y = 0.28, label = stringr::str_wrap("1820: Between country inequality represents 11% of global inequality", width = 20), size = 3) + 
  annotate("text", x = 1980, y = 0.70, label = stringr::str_wrap("1980: Between country inequality represents 57% of global inequality", width = 20), size = 3) +
    annotate("text", x = 1990, y = 0.30, label = stringr::str_wrap("2020: Between country inequality represents 32% of global inequality", width = 20), size = 3)

  • Legend can be place at the bottom: theme(legend.position="bottom")
df_f6 %>% select(year = "...1", 2:3) %>%
  pivot_longer(cols = 2:3, names_to = "type", values_to = "value") %>%
  mutate(types = factor(type, levels = c("Within-country inequality", "Between-country inequality"))) %>%
  ggplot(aes(x = year, y = value, fill = types)) +
  geom_area() +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  scale_x_continuous(breaks = round(seq(1820, 2020, by = 20),1)) + 
  scale_fill_manual(values=rev(scales::hue_pal()(2))) +
  labs(title = "Figure 6. Global income inequality:", 
       subtitle = "Between vs. within country inequality (Theil index), 1820-2020",
       x = "", y = "Share of global inequality (% of total Theil index)", fill = "") + 
  annotate("text", x = 1850, y = 0.28, label = stringr::str_wrap("1820: Between country inequality represents 11% of global inequality", width = 20), size = 3) + 
  annotate("text", x = 1980, y = 0.70, label = stringr::str_wrap("1980: Between country inequality represents 57% of global inequality", width = 20), size = 3) +
    annotate("text", x = 1990, y = 0.30, label = stringr::str_wrap("2020: Between country inequality represents 32% of global inequality", width = 20), size = 3) +
  theme(legend.position="bottom")

Interpretation. The importance of between-country inequality in overall global inequality, as measured by the Theil index, rose between 1820 and 1980 and strongly declined since then. In 2020, between-country inequality makes-up about a third of global inequality between individuals. The rest is due to inequality within countries. Income is measured per capita after pension and unemployement insurance transfers and before income and wealth taxes.
Sources and series: wir2022.wid.world/methodology and Chancel and Piketty (2021).

df_f6 %>% select(year = "...1", 2:3) %>%
  pivot_longer(cols = 2:3, names_to = "type", values_to = "value") %>%
  ggplot(aes(x = year, y = value, fill = type)) +
  geom_area() +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(title = "Figure 6. Global income inequality:", 
       subtitle = "Between vs. within country inequality (Theil index), 1820-2020",
       x = "", y = "Share of global inequality (% of total Theil index)")

2.2.7 F7: Global income inequality, 1820-2020

df_f7 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F7")
df_f7
df_f7 %>% select(year = y, 2:4) %>%
  pivot_longer(cols = 2:4, names_to = "type", values_to = "value") %>%
  ggplot(aes(x = year, y = value, color = type)) +
  stat_smooth(span = 0.25, se = FALSE) +
  scale_x_continuous(breaks = round(seq(1820, 2020, by = 20),1)) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(title = "Figure 7. Global income inequality, 1820-2020", 
       x = "", y = " Share of total world income (%)", color = "") +
  annotate("text", x = 1980, y = 0.20, label = stringr::str_wrap("The global bottom 50% income share remains historically low despite growth in the emerging world in the past decades.", width = 30), size = 3)
`geom_smooth()` using method = 'loess' and formula 'y ~ x'

Interpretation. The share of global income going to top 10% highest incomes at the world level has fluctuated around 50-60% between 1820 and 2020 (50% in 1820, 60% in 1910, 56% in 1980, 61% in 2000, 55% in 2020), while the share going to the bottom 50% lowest incomes has generally been around or below 10% (14% in 1820, 7% in 1910, 5% in 1980, 6% in 2000, 7% in 2020). Global inequality has always been very large. It rose between 1820 and 1910 and shows little long-run trend between 1910 and 2020. Distribution of per capita incomes. Sources and series: see wir2022.wid.world/methodology and Chancel and Piketty (2021).

2.2.8 F8: The rise of private versus the decline of public wealth in rich countries, 1970-2020

df_f8 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F8")
df_f8
df_f8 %>% 
  pivot_longer(!year, names_to = "group", values_to = "value") %>%
  ggplot() +
  stat_smooth(aes(x = year, y = value, color = group), span = 0.25, se = FALSE, size=0.75) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(title = "Figure 8. The rise of private versus the decline of public wealth in rich countries, 1970-2020", 
       x = "", y = "wealth as as % of national income", color = "")
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
 警告:  Removed 50 rows containing non-finite values (stat_smooth).

Interpretation: Public wealth is the sum of all financial and non-financial assets, net of debts, held by governments. Public wealth dropped from 60% of national income in 1970 to -106% in 2020 in the UK. Sources and series: wir2022.wid.world/methodology, Bauluz et al. (2021) and updates.

2.2.9 F9: Average annual wealth growth rate, 1995-2021

df_f9 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F9")
df_f9
df_f9 %>% select(p, wealth = 'Wealth growth 1995-2021') %>%
  ggplot() +
  stat_smooth(aes(x = p, y = wealth), span = 0.25, se = FALSE) +
#  scale_x_continuous(breaks = round(c(seq(0, 90, by = 10), 99.9, 99.99, 99.999,3))) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(title = "Figure 9. Average annual wealth growth rate, 1995-2021", 
       x = "←1% poorest                               Global wealth group                                 0.001% richest→", y = "Per adult annual growth rate in wealth, net of inflation (%)", color = "")
`geom_smooth()` using method = 'loess' and formula 'y ~ x'

Interpretation: Growth rates among the poorest half of the population were between 3% and 4% per year, between 1995 and 2021. Since this group started from very low wealth levels, its absolute levels of growth remained very low. The poorest half of the world population only captured 2.3% of overall wealth growth since 1995. The top 1% benefited from high growth rates (3% to 9% per year). This group captured 38% of total wealth growth between 1995 and 2021. Net household wealth is equal to the sum of financial assets (e.g. equity or bonds) and non-financial assets (e.g. housing or land) owned by individuals, net of their debts.
Sources and series: wir2022.wid.world/methodology.

2.2.10 F10: The share of wealth owned by the global 0.1% and billionaires, 2021

df_f10 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F10")
New names:
• `` -> `...4`
• `` -> `...5`
• `` -> `...6`
df_f10
df_f10 %>% 
  select(year, "Global Billionaire Wealth" = bn_hhweal, "Top 0.01%" = top0.1_hhweal) %>%
  pivot_longer(!year, names_to = "group",".value", values_to = "value") %>%
  ggplot() +
  stat_smooth(aes(x = year, y = value, color = group), span = 0.25, se = FALSE) +
  scale_x_continuous(breaks = round(seq(1995, 2020, by = 5),1)) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  scale_color_manual(values=rev(scales::hue_pal()(2))) +
  labs(title = "Figure 10. Extreme wealth inequality: \nthe rise of global billionaires and top 0.01%, 1995-2021", 
       x = "", y = "Share of total household wealth (%)", color = "")
`geom_smooth()` using method = 'loess' and formula 'y ~ x'

Interpretation: The share of wealth detained by the world’s billionaires rose from 1% of total household wealth in 1995 to nearly 3.5% today. The threshold of top 0.01%, composed of 520 000 adults, grew from €693,000 (PPP) in 1995 to €16,666,000 today. The net household wealth is equal to the sum of financial assets (e.g. equity or bonds) and non-financial assets (e.g. housing or land) owned by individuals, net of their debts.
Sources and series: wir2022.wid.world/methodology, Bauluz et al. (2021) and updates.

2.2.11 F11: Top 1% vs bottom 50% wealth shares in Western Europe and the US, 1910-2020

df_f11 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F11")
df_f11
df_f11 %>% 
  rename(!year, US_bot50 = USbot50, US_top1 = UStop1, EU_bot50 = EUbot50, EU_top1 = EUtop1) %>%
  pivot_longer(!year, names_to = c("group",".value"), names_sep = "_") %>%
  ggplot() +
  stat_smooth(aes(x = year, y = top1, color = group), span = 0.25, se = FALSE) +
  stat_smooth(aes(x = year, y = bot50, color = group), span = 0.25, se = FALSE, linetype = 2) +
  scale_x_continuous(breaks = round(seq(1910, 2020, by = 10),1)) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(title = "Figure 11. Top 1% vs bottom 50% wealth shares \n in Western Europe and the US, 1910-2020", 
       x = "", y = "Share of total personal wealth (%)", color = "") +
  annotate("text", x = 2000, y = 0.50, label = stringr::str_wrap("Wealth inequality has been rising at different speeds after a historical decline. The bottom 50% has always been extremely low.", width = 30), size = 3)
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  span too small.   fewer data values than degrees of freedom.
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  pseudoinverse used at 1909.5
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  neighborhood radius 20.55
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  reciprocal condition number  0
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  There are other near singularities as well. 422.3
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  span too small.   fewer data values than degrees of freedom.
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  pseudoinverse used at 1909.5
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  neighborhood radius 20.55
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  reciprocal condition number  0
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  There are other near singularities as well. 422.3
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  span too small.   fewer data values than degrees of freedom.
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  pseudoinverse used at 1909.5
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  neighborhood radius 20.55
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  reciprocal condition number  0
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  There are other near singularities as well. 422.3
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  span too small.   fewer data values than degrees of freedom.
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  pseudoinverse used at 1909.5
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  neighborhood radius 20.55
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  reciprocal condition number  0
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  There are other near singularities as well. 422.3

Interpretation: The graph presents decennal averages of top 1% personal wealth shares in Western Europe and the US. Between 1910 and 2020, the top 1% was 55% on average in Europe vs. 43% in the US. A century later, the US is almost back to its early 20th century level. Sources and series: wir2022.wid.world/methodology.

df_f11 %>% 
  rename(!year, US_bot50 = USbot50, US_top1 = UStop1, EU_bot50 = EUbot50, EU_top1 = EUtop1) %>%
  pivot_longer(!year, names_to = c("group",".value"), names_sep = "_") %>%
  pivot_longer(3:4, names_to = "type", values_to = "value") %>%
  ggplot() +
  stat_smooth(aes(x = year, y = value, color = group, linetype = type), span = 0.25, se = FALSE) +
  scale_x_continuous(breaks = round(seq(1910, 2020, by = 10),1)) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(title = "Figure 11. Top 1% vs bottom 50% wealth shares \n in Western Europe and the US, 1910-2020", 
       x = "", y = "Share of total personal wealth (%)", color = "", linetype = "") +
  annotate("text", x = 2000, y = 0.50, label = stringr::str_wrap("Wealth inequality has been rising at different speeds after a historical decline. The bottom 50% has always been extremely low.", width = 30), size = 3)
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  span too small.   fewer data values than degrees of freedom.
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  pseudoinverse used at 1909.5
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  neighborhood radius 20.55
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  reciprocal condition number  0
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  There are other near singularities as well. 422.3
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  span too small.   fewer data values than degrees of freedom.
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  pseudoinverse used at 1909.5
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  neighborhood radius 20.55
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  reciprocal condition number  0
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  There are other near singularities as well. 422.3
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  span too small.   fewer data values than degrees of freedom.
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  pseudoinverse used at 1909.5
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  neighborhood radius 20.55
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  reciprocal condition number  0
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  There are other near singularities as well. 422.3
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  span too small.   fewer data values than degrees of freedom.
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  pseudoinverse used at 1909.5
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  neighborhood radius 20.55
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  reciprocal condition number  0
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  There are other near singularities as well. 422.3

df_f11 %>% 
  rename(!year, US_bot50 = USbot50, US_top1 = UStop1, EU_bot50 = EUbot50, EU_top1 = EUtop1) %>%
  pivot_longer(!year, names_to = c("group",".value"), names_sep = "_") %>%
  pivot_longer(3:4, names_to = "type", values_to = "value") %>%
  ggplot() +
  stat_smooth(aes(x = year, y = value, color = group, linetype = type), span = 0.25, se = FALSE) +
  scale_x_continuous(breaks = round(seq(1910, 2020, by = 10),1)) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(title = "Figure 11. Top 1% vs bottom 50% wealth shares \n in Western Europe and the US, 1910-2020", 
       x = "", y = "Share of total personal wealth (%)", color = "", linetype = "") +
  scale_linetype_manual(values = c("dotted","solid")) +
  annotate("text", x = 2000, y = 0.50, label = stringr::str_wrap("Wealth inequality has been rising at different speeds after a historical decline. The bottom 50% has always been extremely low.", width = 30), size = 3)
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  span too small.   fewer data values than degrees of freedom.
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  pseudoinverse used at 1909.5
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  neighborhood radius 20.55
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  reciprocal condition number  0
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  There are other near singularities as well. 422.3
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  span too small.   fewer data values than degrees of freedom.
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  pseudoinverse used at 1909.5
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  neighborhood radius 20.55
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  reciprocal condition number  0
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  There are other near singularities as well. 422.3
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  span too small.   fewer data values than degrees of freedom.
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  pseudoinverse used at 1909.5
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  neighborhood radius 20.55
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  reciprocal condition number  0
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  There are other near singularities as well. 422.3
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  span too small.   fewer data values than degrees of freedom.
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  pseudoinverse used at 1909.5
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  neighborhood radius 20.55
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  reciprocal condition number  0
 simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  で警告がありました: 
  There are other near singularities as well. 422.3

2.2.12 F12: Female share in global labor incomes, 1990-2020

df_f12 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F12")
New names:
• `` -> `...2`
df_f12
df_f12 %>% 
  select(year = "Data needs to be updated", value = ...2) %>%
  filter(!is.na(year)) %>%
  ggplot(aes(x = year, y = value)) +
  geom_col(width = 0.5, fill = "blue") +
  geom_hline(yintercept = 0.5, linetype = 2, colour = "red") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(title = "Figure 12. Female share in global labor incomes, 1990-2020", 
        x = "", y = "") +
  annotate("text", x = 1, y = 0.48, label = "Gender parity", size = 3) +
  annotate("text", x = 5.2, y = 0.47, label = stringr::str_wrap("Women make only 35% of global labor incomes, men make the remaining  65%.", width = 40), size = 3)

Interpretation: The share of female incomes in global labour incomes was 31% in 1990 and nears 35% in 2015-2020. Today, males make up 65% of total labor incomes. Sources and series: wir2022.wid.world/methodology and Neef and Robilliard (2021).

2.2.13 F13: Female labor income share across the world, 1990-2020

Note that the sheet name of F13 has period at the end. Note that summary_sheets[30] =data-F13. with a period.

df_f13 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F13.")
New names:
• `` -> `...1`
df_f13
df_f13 %>% pivot_longer(2:9, names_to = "region", values_to = "value") %>%
  ggplot(aes(x = region, y = value, fill = ...1)) +
  geom_col(position = "dodge") + 
  geom_hline(yintercept = 0.5, linetype = 2, colour = "red") +
  scale_x_discrete(labels = function(x) stringr::str_wrap(x, width = 12)) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(title = "Figure 13. Female labor income share across the world, 1990-2020", 
        x = "", y = "", fill = "") +
  annotate("text", x = 1.2, y = 0.48, label = "Gender parity", size = 3)

Interpretation: The female labour income share rose from 34% to 38% in North America between 1990 and 2020. Sources and series: wir2022.wid.world/methodology and Neef and Robilliard (2021).

2.2.14 F14: Global carbon inequality, 2019. Group contribution to world emissions (%)

Note that the sheet name of F14 has period at the end. Note that summary_sheets[31] =data-F14. with a period.

df_f14 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F14.")
df_f14
  • \n for line break in the title.
df_f14 %>% 
  ggplot(aes(x = Group, y = Share)) +
  geom_col(width = 0.5, fill = "blue") + 
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  labs(title = "Figure 14. Global carbon inequality, \n2019 Group contribution to world emissions (%)", 
       x = "", y = "Share of world emissions (%)")

Interpretation: Personal carbon footprints include emissions from domestic consumption, public and private investments as well as imports and exports of carbon embedded in goods and services traded with the rest of the world. Modeled estimates based on the systematic combination of tax data, household surveys and input-output tables. Emissions split equally within households. Sources and series: wir2022.wid.world/methodology and Chancel (2021).

2.2.15 F15: Per capita emissions acriss the world, 2019

df_f15 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", sheet = "data-F15")
df_f15
df_f15 %>% mutate(region = rep(regionWID[!is.na(regionWID)], each = 3)) %>%
  select(region, group, tcap) %>%
  ggplot(aes(x = region, y = tcap, fill = group)) +
  geom_col(position = "dodge") + 
  scale_x_discrete(labels = function(x) stringr::str_wrap(x, width = 10)) +
  labs(title = "Figure 15 Per capita emissions across the world, 2019", 
       x = "", y = "tonnes of CO2e per person per year", fill = "")

Interpretation: Personal carbon footprints include emissions from domestic consumption, public and private investments as well as imports and exports of carbon embedded in goods and services traded with the rest of the world. Modeled estimates based on the systematic combination of tax data, household surveys and input-output tables. Emissions split equally within households. Sources and series: wir2022.wid.world/methodology and Chancel (2021).

region_test <- rep(df_f15$regionWID[!is.na(df_f15$regionWID)], each = 3)
region_test
 [1] "East Asia"               "East Asia"               "East Asia"              
 [4] "Europe"                  "Europe"                  "Europe"                 
 [7] "North America"           "North America"           "North America"          
[10] "South & South-East Asia" "South & South-East Asia" "South & South-East Asia"
[13] "Russia & Central Asia"   "Russia & Central Asia"   "Russia & Central Asia"  
[16] "MENA"                    "MENA"                    "MENA"                   
[19] "Latin America"           "Latin America"           "Latin America"          
[22] "Sub-Saharan Africa"      "Sub-Saharan Africa"      "Sub-Saharan Africa"     

2.2.16 T1 Global millionaires and billionaires, 2021

Check the format of the sheet and add skip=4, n_max=7.

df_t1 <- read_excel("data/WIR2022TablesFigures-Summary.xlsx", 
                    sheet = "T1", skip = 4, n_max = 7)
df_t1

Interpretation: In 2021, there were 62.2 million people in the world owning more than $1 million (measured at Market Exchange Rates). Their average wealth was $ 2.8 million, representing a total of $174 trillion. In our Tax scenario 2, a global progressive wealth tax would yield 2.1% of global income, taking into account capital depreciation and evasion. Sources and series: wir2022.wid.world/methodology.

LS0tCnRpdGxlOiAiV29ybGQgSW5lcXVhbGl0eSBSZXBvcnQgMjAyMiIKYXV0aG9yOiAiRFMtU0wiCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIgCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiMgICAgdG9jOiB0cnVlCiMgICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKIyBJbnRyb2R1Y3Rpb24KCiMjIFdJUjIwMjIKCiogRXhlY3V0aXZlIFN1bW1hcnk6IGh0dHBzOi8vd2lyMjAyMi53aWQud29ybGQvZXhlY3V0aXZlLXN1bW1hcnkvCiogTWV0aG9kb2xvZ3k6IGh0dHBzOi8vd2lyMjAyMi53aWQud29ybGQvbWV0aG9kb2xvZ3kvCgojIEV4ZWN1dGl2ZSBTdW1tYXJ5CgojIyBTZXR1cAoKKiBEYXRhOiBodHRwczovL3dpcjIwMjIud2lkLndvcmxkL3d3dy1zaXRlL3VwbG9hZHMvMjAyMi8wMy9XSVIyMDIyVGFibGVzRmlndXJlcy1TdW1tYXJ5Lnhsc3gKKiBEYXRhIGFyZSBpbiBFeGNlbCBmb3JtYXQgYW5kIGNoYXJ0cyBhcmUgYWxzbyBjcmVhdGVkIGluIEV4Y2VsLgoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHJlYWR4bCkKYGBgCgpgYGB7ciBzdW1tYXJ5LWRhdGEsIGNhc2ggPSBUUlVFLCBldmFsID0gRkFMU0V9CnVybF9zdW1tYXJ5IDwtICJodHRwczovL3dpcjIwMjIud2lkLndvcmxkL3d3dy1zaXRlL3VwbG9hZHMvMjAyMi8wMy9XSVIyMDIyVGFibGVzRmlndXJlcy1TdW1tYXJ5Lnhsc3giCmRvd25sb2FkLmZpbGUodXJsID0gdXJsX3N1bW1hcnksIGRlc3RmaWxlID0gImRhdGEvV0lSMjAyMlRhYmxlc0ZpZ3VyZXMtU3VtbWFyeS54bHN4IikgCmBgYAoKYGBge3Igc3VtbWFyeS1kYXRhLXNoZWV0LCBjYXNoID0gVFJVRX0Kc3VtbWFyeV9zaGVldHMgPC0gZXhjZWxfc2hlZXRzKCJkYXRhL1dJUjIwMjJUYWJsZXNGaWd1cmVzLVN1bW1hcnkueGxzeCIpCnN1bW1hcnlfc2hlZXRzCmBgYAoKKiBOb3RlIHRoYXQgc29tZSBvZiB0aGUgc2hlZXQgbmFtZXMgY29udGFpbiBhIHBlcmlvZC4KCmBgYHtyfQpkZl9pbmRleCA8LSByZWFkX2V4Y2VsKCJkYXRhL1dJUjIwMjJUYWJsZXNGaWd1cmVzLVN1bW1hcnkueGxzeCIsIHNoZWV0ID0gIkluZGV4IikKZGZfaW5kZXgKYGBgCiogVGhlIGxpc3Qgb2YgdGhlIHRpdGxlcyBvZiB0aGUgdGFibGVzIGFuZCB0aGUgZmlndXJlcy4KCiMjIERhdGEgYW5kIENoYXJ0cwoKIyMjIEYxOiBHbG9iYWwgaW5jb21lIGFuZCB3ZWFsdGggaW5lcXVhbGl0eSwgMjAyMQoKYGBge3IgZGF0YS1mMSwgY2FzaCA9IFRSVUV9CmRmX2YxIDwtIHJlYWRfZXhjZWwoImRhdGEvV0lSMjAyMlRhYmxlc0ZpZ3VyZXMtU3VtbWFyeS54bHN4Iiwgc2hlZXQgPSAiZGF0YS1GMSIpCmRmX2YxCmBgYAoKYGBge3J9CmRmX2YxICU+JSBzZWxlY3QoY2F0ID0gLi4uMSwgMjo0KSAlPiUKICBwaXZvdF9sb25nZXIoMjo0LCBuYW1lc190byA9ICJsZXZlbCIsIHZhbHVlc190byA9ICJ2YWx1ZSIpICU+JQogIGdncGxvdChhZXMoeCA9IGNhdCwgeSA9IHZhbHVlLCBmaWxsID0gbGV2ZWwpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArIAogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBsYWJzKHRpdGxlID0gIkZpZ3VyZSAxLiBHbG9iYWwgaW5jb21lIGFuZCB3ZWFsdGggaW5lcXVhbGl0eSwgMjAyMSIsCiAgICAgICB4ID0gIiIsIHkgPSAiU2hhcmUgb2YgdG90YWwgaW5jb21lIG9yIHdlYWx0aCIsIGZpbGwgPSAiIikKYGBgCioqSW50ZXJwcmV0YXRpb24qKjogVGhlIGdsb2JhbCBib3R0b20gNTAlIGNhcHR1cmVzIDguNSUgb2YgdG90YWwgaW5jb21lIG1lYXN1cmVkIGF0IFB1cmNoYXNpbmcgUG93ZXIgUGFyaXR5IChQUFApLiBUaGUgZ2xvYmFsIGJvdHRvbSA1MCUgb3ducyAyJSBvZiB3ZWFsdGggKGF0IFB1cmNoYXNpbmcgUG93ZXIgUGFyaXR5KS4gVGhlIGdsb2JhbCB0b3AgMTAlIG93bnMgNzYlIG9mIHRvdGFsIEhvdXNlaG9sZCB3ZWFsdGggYW5kIGNhcHR1cmVzIDUyJSBvZiB0b3RhbCBpbmNvbWUgaW4gMjAyMS4gTm90ZSB0aGF0IHRvcCB3ZWFsdGggaG9sZGVycyBhcmUgbm90IG5lY2Vzc2FyaWx5IHRvcCBpbmNvbWUgaG9sZGVycy4gSW5jb21lcyBhcmUgbWVhc3VyZWQgYWZ0ZXIgdGhlIG9wZXJhdGlvbiBvZiBwZW5zaW9uIGFuZCB1bmVtcGxveW1lbnQgc3lzdGVtcyBhbmQgYmVmb3JlIHRheGVzIGFuZCB0cmFuc2ZlcnMuICAgCioqU291cmNlcyBhbmQgc2VyaWVzKio6IHdpcjIwMjIud2lkLndvcmxkL21ldGhvZG9sb2d5LgoKCiMjIyBGMjogVGhlIHBvb3Jlc3QgaGFsZiBsYWdzIGJlaGluZDogQm90dG9tIDUwJSwgbWlkZGxlIDQwJSBhbmQgdG9wIDEwJSBpbmNvbWUgc2hhcmVzIGFjcm9zcyB0aGUgd29ybGQgaW4gMjAyMQoKYGBge3IgZGF0YS1mMiwgY2FzaCA9IFRSVUV9CmRmX2YyIDwtIHJlYWRfZXhjZWwoImRhdGEvV0lSMjAyMlRhYmxlc0ZpZ3VyZXMtU3VtbWFyeS54bHN4Iiwgc2hlZXQgPSAiZGF0YS1GMiIpCmRmX2YyCmBgYAoKYGBge3J9CmRmX2YyICU+JSBwaXZvdF9sb25nZXIoMzo1LCBuYW1lc190byA9ICJsZXZlbCIsIHZhbHVlc190byA9ICJ2YWx1ZSIpICU+JQogIGdncGxvdChhZXMoeCA9IGlzbywgeSA9IHZhbHVlLCBmaWxsID0gbGV2ZWwpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArIAogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gZnVuY3Rpb24oeCkgc3RyaW5ncjo6c3RyX3dyYXAoeCwgd2lkdGggPSAxMCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgbGFicyh0aXRsZSA9ICJGaWd1cmUgMi4gVGhlIHBvb3Jlc3QgaGFsZiBsYWdzIGJlaGluZCIsIAogICAgICAgc3VidGl0bGUgPSAiQm90dG9tIDUwJSwgbWlkZGxlIDQwJSBhbmQgdG9wIDEwJSBpbmNvbWUgc2hhcmVzIGFjcm9zcyB0aGUgd29ybGQgaW4gMjAyMSIsCiAgICAgICB4ID0gIiIsIHkgPSAiU2hhcmUgb2YgbmF0aW9uYWwgaW5jb21lICglKSIsIGZpbGwgPSAiIikKYGBgCioqSW50ZXJwcmV0YXRpb24qKjogSW4gTGF0aW4gQW1lcmljYSwgdGhlIHRvcCAxMCUgY2FwdHVyZXMgNTUlIG9mIG5hdGlvbmFsIGluY29tZSwgY29tcGFyZWQgdG8gMzYlIGluIEV1cm9wZS4gSW5jb21lIGlzIG1lYXN1cmVkIGFmdGVyIHBlbnNpb24gYW5kIHVuZW1wbG95bWVudCBjb250cmlidXRpb25zIGFuZCBiZW5lZml0cyBwYWlkIGFuZCByZWNlaXZlZCBieSBpbmRpdmlkdWFscyBidXQgYmVmb3JlIGluY29tZSB0YXhlcyBhbmQgb3RoZXIgdHJhbnNmZXJzLiAgIAoqKlNvdXJjZXMgYW5kIHNlcmllcyoqOiB3d3cud2lyMjAyMi53aWQud29ybGQvbWV0aG9kb2xvZ3kuCgoKYGBge3J9CmRmX2YyICU+JSBwaXZvdF9sb25nZXIoMzo1LCBuYW1lc190byA9ICJsZXZlbCIsIHZhbHVlc190byA9ICJ2YWx1ZSIpICU+JQogIGdncGxvdChhZXMoeCA9IGlzbywgeSA9IHZhbHVlLCBmaWxsID0gbGV2ZWwpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIHZqdXN0ID0gMSwgaGp1c3Q9MSkpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKwogIGxhYnModGl0bGUgPSAiRmlndXJlIDIuIFRoZSBwb29yZXN0IGhhbGYgbGFncyBiZWhpbmQiLCAKICAgICAgIHN1YnRpdGxlID0gIkJvdHRvbSA1MCUsIG1pZGRsZSA0MCUgYW5kIHRvcCAxMCUgaW5jb21lIHNoYXJlcyBhY3Jvc3MgdGhlIHdvcmxkIGluIDIwMjEiLAogICAgICAgeCA9ICIiLCB5ID0gIlNoYXJlIG9mIG5hdGlvbmFsIGluY29tZSAoJSkiLCBmaWxsID0gIiIpCmBgYAoKIyMjIEYzOiBUb3AgMTAvQm90dG9tIDUwIGluY29tZSBnYXBzIGFjcm9zcyB0aGUgd29ybGQsIDIwMjEKCmBgYHtyIGRhdGEtZjMsIGNhc2ggPSBUUlVFfQpkZl9mMyA8LSByZWFkX2V4Y2VsKCJkYXRhL1dJUjIwMjJUYWJsZXNGaWd1cmVzLVN1bW1hcnkueGxzeCIsIHNoZWV0ID0gImRhdGEtRjMiKQpkZl9mMwpgYGAKCiMjIyBGNDogVGhlIGV4dHJlbWUgY29uY2VudHJhdGlvbiBvZiBjYXBpdGFsOiB3ZWFsdGggaW5lcXVhbGl0eSBhY3Jvc3MgdGhlIHdvcmxkLCAyMDIxCgpgYGB7ciBkYXRhLWY0LCBjYXNoID0gVFJVRX0KZGZfZjQgPC0gcmVhZF9leGNlbCgiZGF0YS9XSVIyMDIyVGFibGVzRmlndXJlcy1TdW1tYXJ5Lnhsc3giLCBzaGVldCA9ICJkYXRhLUY0IikKZGZfZjQKYGBgCgoqIFdyYXAgbG9uZyBsYWJlbDogYHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gZnVuY3Rpb24oeCkgc3RyaW5ncjo6c3RyX3dyYXAoeCwgd2lkdGggPSAxMCkpYAoqIFBlciBDZW50OiBgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSlgCgpgYGB7cn0KZGZfZjQgJT4lIHBpdm90X2xvbmdlcigzOjUsIG5hbWVzX3RvID0gImxldmVsIiwgdmFsdWVzX3RvID0gInZhbHVlIikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gaXNvLCB5ID0gdmFsdWUsIGZpbGwgPSBsZXZlbCkpICsKICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpICsgCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBmdW5jdGlvbih4KSBzdHJpbmdyOjpzdHJfd3JhcCh4LCB3aWR0aCA9IDEwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBsYWJzKHRpdGxlID0gIkZpZ3VyZSA0LiBUaGUgZXh0cmVtZSBjb25jZW50cmF0aW9uIG9mIGNhcGl0YWw6IiwgCiAgICAgICBzdWJ0aXRsZSA9ICJ3ZWFsdGggaW5lcXVhbGl0eSBhY3Jvc3MgdGhlIHdvcmxkLCAyMDIxIiwKICAgICAgIHggPSAiIiwgeSA9ICJTaGFyZSBvZiBuYXRpb25hbCB3ZWFsdGggKCUpIiwgZmlsbCA9ICIiKQpgYGAKKipJbnRlcnByZXRhdGlvbioqOiAgVGhlIFRvcCAxMCUgaW4gTGF0aW4gQW1lcmljYSBjYXB0dXJlcyA3NyUgb2YgdG90YWwgaG91c2Vob2xkIHdlYWx0aCwgdmVyc3VzIDIyJSBmb3IgdGhlIE1pZGRsZSA0MCUgYW5kIDElIGZvciB0aGUgQm90dG9tIDUwJS4gSW4gRXVyb3BlLCB0aGUgVG9wIDEwJSBvd25zIDU4JSBvZiB0b3RhbCB3ZWFsdGgsIHZlcnN1cyAzOCUgZm9yIHRoZSBNaWRkbGUgNDAlIGFuZCA0JSBmb3IgdGhlIEJvdHRvbSA1MCUuICAgCioqU291cmNlcyBhbmQgc2VyaWVzKio6IHdpcjIwMjIud2lkLndvcmxkL21ldGhvZG9sb2d5LgoKCiMjIyBGNTogR2xvYmFsIGluY29tZSBpbmVxdWFsaXR5OiBUMTAvQjUwIHJhdGlvLCAxODIwLTIwMjAKCmBgYHtyIGRhdGEtZjUsIGNhc2ggPSBUUlVFfQpkZl9mNSA8LSByZWFkX2V4Y2VsKCJkYXRhL1dJUjIwMjJUYWJsZXNGaWd1cmVzLVN1bW1hcnkueGxzeCIsIHNoZWV0ID0gImRhdGEtRjUiKQpkZl9mNQpgYGAKKipVc2UgYHNwYW5gIEFyZ3VtZW50IHRvIEZpdCB0byBEYXRhKioKCiogeS1heGlzOiBgbGltcyh5ID0gYygxMCw3MCkpYAoqIGBzdHJpbmdyOjpzdHJfd3JhcCgibG9uZyB0ZXh0Iiwgd2lkdGggPSBzaXplKWAKKiBgYW5ub3RhdGVgIHdpdGggYHNpemUgPSBmb250c2l6ZWAKCmBgYHtyfQpkZl9mNSAlPiUgc2VsZWN0KHllYXIgPSB5LCByYXRpbyA9IHQxMGI1MCkgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHJhdGlvKSkgKyAKICBsaW1zKHkgPSBjKDEwLDcwKSkgKyAKICBzdGF0X3Ntb290aChzcGFuID0gMC4yNSwgc2UgPSBGQUxTRSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gcm91bmQoc2VxKDE4MjAsIDIwMjAsIGJ5ID0gMjApLDEpKSArIAogIGxhYnModGl0bGUgPSAiRmlndXJlIDUuIEdsb2JhbCBpbmNvbWUgaW5lcXVhbGl0eTpUMTAvQjUwIHJhdGlvLCAxODIwLTIwMjAiLCAKICAgICAgIHggPSAiIiwgeSA9IHN0cmluZ3I6OnN0cl93cmFwKCJSYXRpbyBvZiB0b3AgMTAlIGF2ZXJhZ2UgaW5jb21lIHRvIGJvdHRvbSA1MCUgYXZlcmFnZSBpbmNvbWUiLCB3aWR0aCA9IDM1KSkgKwogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDE4NDAsIHkgPSAzMiwgbGFiZWwgPSBzdHJpbmdyOjpzdHJfd3JhcCgiMTgyMDogYXZlcmFnZSBpbmNvbWUgb2YgdGhlIGdsb2JhbCB0b3AgMTAlIGlzIDE4eCBoaWdoZXIgdGhhbiBhdmVyYWdlIGluY29tZSBvZiB0aGUgYm90dG9tIDUwJSIsIHdpZHRoID0gMjApLCBzaXplID0gMykgKyAKICBhbm5vdGF0ZSgidGV4dCIsIHggPSAxOTEwLCB5ID0gNDksIGxhYmVsID0gc3RyaW5ncjo6c3RyX3dyYXAoIjE5MTA6IGF2ZXJhZ2UgaW5jb21lIG9mIHRoZSBnbG9iYWwgdG9wIDEwJSBpcyA0MXggaGlnaGVyIHRoYW4gYXZlcmFnZSBpbmNvbWUgb2YgdGhlIGJvdHRvbSA1MCUiLCB3aWR0aCA9IDIwKSwgc2l6ZSA9IDMpICsKICAgIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDE5ODAsIHkgPSA2MCwgbGFiZWwgPSBzdHJpbmdyOjpzdHJfd3JhcCgiMTk4MDogYXZlcmFnZSBpbmNvbWUgb2YgdGhlIGdsb2JhbCB0b3AgMTAlIGlzIDUzeCBoaWdoZXIgdGhhbiBhdmVyYWdlIGluY29tZSBvZiB0aGUgYm90dG9tIDUwJSIsIHdpZHRoID0gMjApLCBzaXplID0gMykgKwogICAgYW5ub3RhdGUoInRleHQiLCB4ID0gMjAxMCwgeSA9IDMyLCBsYWJlbCA9IHN0cmluZ3I6OnN0cl93cmFwKCIyMDIwOiBhdmVyYWdlIGluY29tZSBvZiB0aGUgZ2xvYmFsIHRvcCAxMCUgaXMgMzh4IGhpZ2hlciB0aGFuIGF2ZXJhZ2UgaW5jb21lIG9mIHRoZSBib3R0b20gNTAlIiwgd2lkdGggPSAyMCksIHNpemUgPSAzKQpgYGAKKipJbnRlcnByZXRhdGlvbioqLiBHbG9iYWwgaW5lcXVhbGl0eSwgYXMgbWVhc3VyZWQgYnkgdGhlIHJhdGlvIFQxMC9CNTAgYmV0d2VlbiB0aGUgYXZlcmFnZSBpbmNvbWUgb2YgdGhlIHRvcCAxMCUgYW5kIHRoZSBhdmVyYWdlIGluY29tZSBvZiB0aGUgYm90dG9tIDUwJSwgbW9yZSB0aGFuIGRvdWJsZWQgYmV0d2VlbiBiZXR3ZWVuIDE4MjAgYW5kIDE5MTAsIGZyb20gbGVzcyB0aGFuIDIwIHRvIGFib3V0IDQwLCBhbmQgc3RhYmlsaXplZCBhcm91bmQgNDAgYmV0d2VlbiAxOTEwIGFuZCAyMDIwLiBJdCBpcyB0b28gZWFybHkgdG8gc2F5IHdoZXRoZXIgdGhlIGRlY2xpbmUgaW4gZ2xvYmFsIGluZXF1YWxpdHkgb2JzZXJ2ZWQgc2luY2UgMjAwOCB3aWxsIGNvbnRpbnVlLiBJbmNvbWUgaXMgbWVhc3VyZWQgcGVyIGNhcGl0YSBhZnRlciBwZW5zaW9uIGFuZCB1bmVtcGxveWVtZW50IGluc3VyYW5jZSB0cmFuc2ZlcnMgYW5kIGJlZm9yZSBpbmNvbWUgYW5kIHdlYWx0aCB0YXhlcy4gICAKKipTb3VyY2VzIGFuZCBzZXJpZXMqKjogd2lyMjAyMi53aWQud29ybGQvbG1ldGhvZG9sb2d5IGFuZCBDaGFuY2VsIGFuZCBQaWtldHR5ICgyMDIxKS4uCgoqIGBnZ2ZvcmNlOjpnZW9tX21hcmtfcmVjdGAgd2lsbCBhZGQgYW5ub3RhdGlvbiBpbiBhIGJveC4KCioqTGluZSBQbG90IGFuZCBMT0VTUyoqCgpgYGB7cn0KZGZfZjUgJT4lIHNlbGVjdCh5ZWFyID0geSwgcmF0aW8gPSB0MTBiNTApICU+JQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSByYXRpbykpICsKICBnZW9tX2xpbmUoKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSkgKyAKICBsYWJzKHRpdGxlID0gIkZpZ3VyZSA1LiBHbG9iYWwgaW5jb21lIGluZXF1YWxpdHk6IiwgCiAgICAgICBzdWJ0aXRsZSA9ICJUMTAvQjUwIHJhdGlvLCAxODIwLTIwMjAiLAogICAgICAgeCA9ICIiLCB5ID0gIlJhdGlvIG9mIHRvcCAxMCUgYXZlcmFnZSBpbmNvbWUgdG8gYm90dG9tIDUwJSBhdmVyYWdlIGluY29tZSIpCmBgYAoKKipHQU0gU21vb3RoaW5nIHdpdGggMjQgUG9pbnRzKioKCmBgYHtyfQpkZl9mNSAlPiUgc2VsZWN0KHllYXIgPSB5LCByYXRpbyA9IHQxMGI1MCkgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHJhdGlvKSkgKwogIHN0YXRfc21vb3RoKG1ldGhvZCA9ICJnYW0iLCBmb3JtdWxhID0geSB+IHMoeCwgayA9IDI0KSwgc2UgPSBGQUxTRSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gcm91bmQoc2VxKG1pbihkZl9mNSR5KSwgbWF4KGRmX2Y1JHkpLCBieSA9IDIwKSwxKSkgKyAKICBsYWJzKHRpdGxlID0gIkZpZ3VyZSA1LiBHbG9iYWwgaW5jb21lIGluZXF1YWxpdHk6VDEwL0I1MCByYXRpbywgMTgyMC0yMDIwIiwgCiAgICAgICB4ID0gIiIsIHkgPSBzdHJpbmdyOjpzdHJfd3JhcCgiUmF0aW8gb2YgdG9wIDEwJSBhdmVyYWdlIGluY29tZSB0byBib3R0b20gNTAlIGF2ZXJhZ2UgaW5jb21lIiwgd2lkdGggPSAzNSkpCmBgYAoKKipQb2x5bm9taWFsIEFwcHJveGltYXRpb24gb2YgRGVncmVlIDYqKgoKYGBge3J9CmRmX2Y1ICU+JSBzZWxlY3QoeWVhciA9IHksIHJhdGlvID0gdDEwYjUwKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcmF0aW8pKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBmb3JtdWxhID0geSB+IHBvbHkoeCwgNiksIHNlID0gRkFMU0UpICsgCiAgbGFicyh0aXRsZSA9ICJGaWd1cmUgNS4gR2xvYmFsIGluY29tZSBpbmVxdWFsaXR5OiIsIAogICAgICAgc3VidGl0bGUgPSAiVDEwL0I1MCByYXRpbywgMTgyMC0yMDIwIiwKICAgICAgIHggPSAiIiwgeSA9ICJSYXRpbyBvZiB0b3AgMTAlIGF2ZXJhZ2UgaW5jb21lIHRvIGJvdHRvbSA1MCUgYXZlcmFnZSBpbmNvbWUiKQpgYGAKCiMjIyBGNjogR2xvYmFsIGluY29tZSBpbmVxdWFsaXR5OiBCZXR3ZWVuIHZzLiBXaXRoaW4gY291bnRyeSBpbmVxdWFsaXR5IChUaGVpbCBpbmRleCksIDE4MjAtMjAyMAoKYGBge3IgZGF0YS1mNiwgY2FzaCA9IFRSVUV9CmRmX2Y2IDwtIHJlYWRfZXhjZWwoImRhdGEvV0lSMjAyMlRhYmxlc0ZpZ3VyZXMtU3VtbWFyeS54bHN4Iiwgc2hlZXQgPSAiZGF0YS1GNiIpCmRmX2Y2CmBgYAoKKiBgcmV2KHNjYWxlczo6aHVlX3BhbCgpKDIpKWA6IHJldmVyc2luZyB0aGUgb3JkZXIgb2YgY29sb3JzIHRvIGZpbGwuCgpgYGB7cn0KZGZfZjYgJT4lIHNlbGVjdCh5ZWFyID0gIi4uLjEiLCAyOjMpICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gMjozLCBuYW1lc190byA9ICJ0eXBlIiwgdmFsdWVzX3RvID0gInZhbHVlIikgJT4lCiAgbXV0YXRlKHR5cGVzID0gZmFjdG9yKHR5cGUsIGxldmVscyA9IGMoIldpdGhpbi1jb3VudHJ5IGluZXF1YWxpdHkiLCAiQmV0d2Vlbi1jb3VudHJ5IGluZXF1YWxpdHkiKSkpICU+JQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSB2YWx1ZSwgZmlsbCA9IHR5cGVzKSkgKwogIGdlb21fYXJlYSgpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHJvdW5kKHNlcSgxODIwLCAyMDIwLCBieSA9IDIwKSwxKSkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9cmV2KHNjYWxlczo6aHVlX3BhbCgpKDIpKSwgbGFiZWxzID0gZnVuY3Rpb24oeCkgc3RyX3dyYXAoeCwgd2lkdGggPSAxNSkpICsKICBsYWJzKHRpdGxlID0gIkZpZ3VyZSA2LiBHbG9iYWwgaW5jb21lIGluZXF1YWxpdHk6IiwgCiAgICAgICBzdWJ0aXRsZSA9ICJCZXR3ZWVuIHZzLiB3aXRoaW4gY291bnRyeSBpbmVxdWFsaXR5IChUaGVpbCBpbmRleCksIDE4MjAtMjAyMCIsCiAgICAgICB4ID0gIiIsIHkgPSAiU2hhcmUgb2YgZ2xvYmFsIGluZXF1YWxpdHkgKCUgb2YgdG90YWwgVGhlaWwgaW5kZXgpIiwgZmlsbCA9ICIiKSArIAogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDE4NTAsIHkgPSAwLjI4LCBsYWJlbCA9IHN0cmluZ3I6OnN0cl93cmFwKCIxODIwOiBCZXR3ZWVuIGNvdW50cnkgaW5lcXVhbGl0eSByZXByZXNlbnRzIDExJSBvZiBnbG9iYWwgaW5lcXVhbGl0eSIsIHdpZHRoID0gMjApLCBzaXplID0gMykgKyAKICBhbm5vdGF0ZSgidGV4dCIsIHggPSAxOTgwLCB5ID0gMC43MCwgbGFiZWwgPSBzdHJpbmdyOjpzdHJfd3JhcCgiMTk4MDogQmV0d2VlbiBjb3VudHJ5IGluZXF1YWxpdHkgcmVwcmVzZW50cyA1NyUgb2YgZ2xvYmFsIGluZXF1YWxpdHkiLCB3aWR0aCA9IDIwKSwgc2l6ZSA9IDMpICsKICAgIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDE5OTAsIHkgPSAwLjMwLCBsYWJlbCA9IHN0cmluZ3I6OnN0cl93cmFwKCIyMDIwOiBCZXR3ZWVuIGNvdW50cnkgaW5lcXVhbGl0eSByZXByZXNlbnRzIDMyJSBvZiBnbG9iYWwgaW5lcXVhbGl0eSIsIHdpZHRoID0gMjApLCBzaXplID0gMykKYGBgCiogTGVnZW5kIGNhbiBiZSBwbGFjZSBhdCB0aGUgYm90dG9tOiBgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKWAKCmBgYHtyfQpkZl9mNiAlPiUgc2VsZWN0KHllYXIgPSAiLi4uMSIsIDI6MykgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAyOjMsIG5hbWVzX3RvID0gInR5cGUiLCB2YWx1ZXNfdG8gPSAidmFsdWUiKSAlPiUKICBtdXRhdGUodHlwZXMgPSBmYWN0b3IodHlwZSwgbGV2ZWxzID0gYygiV2l0aGluLWNvdW50cnkgaW5lcXVhbGl0eSIsICJCZXR3ZWVuLWNvdW50cnkgaW5lcXVhbGl0eSIpKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHZhbHVlLCBmaWxsID0gdHlwZXMpKSArCiAgZ2VvbV9hcmVhKCkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gcm91bmQoc2VxKDE4MjAsIDIwMjAsIGJ5ID0gMjApLDEpKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1yZXYoc2NhbGVzOjpodWVfcGFsKCkoMikpKSArCiAgbGFicyh0aXRsZSA9ICJGaWd1cmUgNi4gR2xvYmFsIGluY29tZSBpbmVxdWFsaXR5OiIsIAogICAgICAgc3VidGl0bGUgPSAiQmV0d2VlbiB2cy4gd2l0aGluIGNvdW50cnkgaW5lcXVhbGl0eSAoVGhlaWwgaW5kZXgpLCAxODIwLTIwMjAiLAogICAgICAgeCA9ICIiLCB5ID0gIlNoYXJlIG9mIGdsb2JhbCBpbmVxdWFsaXR5ICglIG9mIHRvdGFsIFRoZWlsIGluZGV4KSIsIGZpbGwgPSAiIikgKyAKICBhbm5vdGF0ZSgidGV4dCIsIHggPSAxODUwLCB5ID0gMC4yOCwgbGFiZWwgPSBzdHJpbmdyOjpzdHJfd3JhcCgiMTgyMDogQmV0d2VlbiBjb3VudHJ5IGluZXF1YWxpdHkgcmVwcmVzZW50cyAxMSUgb2YgZ2xvYmFsIGluZXF1YWxpdHkiLCB3aWR0aCA9IDIwKSwgc2l6ZSA9IDMpICsgCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gMTk4MCwgeSA9IDAuNzAsIGxhYmVsID0gc3RyaW5ncjo6c3RyX3dyYXAoIjE5ODA6IEJldHdlZW4gY291bnRyeSBpbmVxdWFsaXR5IHJlcHJlc2VudHMgNTclIG9mIGdsb2JhbCBpbmVxdWFsaXR5Iiwgd2lkdGggPSAyMCksIHNpemUgPSAzKSArCiAgICBhbm5vdGF0ZSgidGV4dCIsIHggPSAxOTkwLCB5ID0gMC4zMCwgbGFiZWwgPSBzdHJpbmdyOjpzdHJfd3JhcCgiMjAyMDogQmV0d2VlbiBjb3VudHJ5IGluZXF1YWxpdHkgcmVwcmVzZW50cyAzMiUgb2YgZ2xvYmFsIGluZXF1YWxpdHkiLCB3aWR0aCA9IDIwKSwgc2l6ZSA9IDMpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIpCmBgYAoqKkludGVycHJldGF0aW9uKiouIFRoZSBpbXBvcnRhbmNlIG9mIGJldHdlZW4tY291bnRyeSBpbmVxdWFsaXR5IGluIG92ZXJhbGwgZ2xvYmFsIGluZXF1YWxpdHksIGFzIG1lYXN1cmVkIGJ5IHRoZSBUaGVpbCBpbmRleCwgcm9zZSBiZXR3ZWVuIDE4MjAgYW5kIDE5ODAgYW5kIHN0cm9uZ2x5IGRlY2xpbmVkIHNpbmNlIHRoZW4uIEluIDIwMjAsIGJldHdlZW4tY291bnRyeSBpbmVxdWFsaXR5IG1ha2VzLXVwIGFib3V0IGEgdGhpcmQgb2YgZ2xvYmFsIGluZXF1YWxpdHkgYmV0d2VlbiBpbmRpdmlkdWFscy4gVGhlIHJlc3QgaXMgZHVlIHRvIGluZXF1YWxpdHkgd2l0aGluIGNvdW50cmllcy4gSW5jb21lIGlzIG1lYXN1cmVkIHBlciBjYXBpdGEgYWZ0ZXIgcGVuc2lvbiBhbmQgdW5lbXBsb3llbWVudCBpbnN1cmFuY2UgdHJhbnNmZXJzIGFuZCBiZWZvcmUgaW5jb21lIGFuZCB3ZWFsdGggdGF4ZXMuICAgCioqU291cmNlcyBhbmQgc2VyaWVzKio6IHdpcjIwMjIud2lkLndvcmxkL21ldGhvZG9sb2d5IGFuZCBDaGFuY2VsIGFuZCBQaWtldHR5ICgyMDIxKS4KCgpgYGB7cn0KZGZfZjYgJT4lIHNlbGVjdCh5ZWFyID0gIi4uLjEiLCAyOjMpICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gMjozLCBuYW1lc190byA9ICJ0eXBlIiwgdmFsdWVzX3RvID0gInZhbHVlIikgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHZhbHVlLCBmaWxsID0gdHlwZSkpICsKICBnZW9tX2FyZWEoKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKwogIGxhYnModGl0bGUgPSAiRmlndXJlIDYuIEdsb2JhbCBpbmNvbWUgaW5lcXVhbGl0eToiLCAKICAgICAgIHN1YnRpdGxlID0gIkJldHdlZW4gdnMuIHdpdGhpbiBjb3VudHJ5IGluZXF1YWxpdHkgKFRoZWlsIGluZGV4KSwgMTgyMC0yMDIwIiwKICAgICAgIHggPSAiIiwgeSA9ICJTaGFyZSBvZiBnbG9iYWwgaW5lcXVhbGl0eSAoJSBvZiB0b3RhbCBUaGVpbCBpbmRleCkiKQpgYGAKCiMjIyBGNzogR2xvYmFsIGluY29tZSBpbmVxdWFsaXR5LCAxODIwLTIwMjAKCmBgYHtyIGRhdGEtZjcsIGNhc2ggPSBUUlVFfQpkZl9mNyA8LSByZWFkX2V4Y2VsKCJkYXRhL1dJUjIwMjJUYWJsZXNGaWd1cmVzLVN1bW1hcnkueGxzeCIsIHNoZWV0ID0gImRhdGEtRjciKQpkZl9mNwpgYGAKCmBgYHtyfQpkZl9mNyAlPiUgc2VsZWN0KHllYXIgPSB5LCAyOjQpICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gMjo0LCBuYW1lc190byA9ICJ0eXBlIiwgdmFsdWVzX3RvID0gInZhbHVlIikgJT4lCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHZhbHVlLCBjb2xvciA9IHR5cGUpKSArCiAgc3RhdF9zbW9vdGgoc3BhbiA9IDAuMjUsIHNlID0gRkFMU0UpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gcm91bmQoc2VxKDE4MjAsIDIwMjAsIGJ5ID0gMjApLDEpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKwogIGxhYnModGl0bGUgPSAiRmlndXJlIDcuIEdsb2JhbCBpbmNvbWUgaW5lcXVhbGl0eSwgMTgyMC0yMDIwIiwgCiAgICAgICB4ID0gIiIsIHkgPSAiIFNoYXJlIG9mIHRvdGFsIHdvcmxkIGluY29tZSAoJSkiLCBjb2xvciA9ICIiKSArCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gMTk4MCwgeSA9IDAuMjAsIGxhYmVsID0gc3RyaW5ncjo6c3RyX3dyYXAoIlRoZSBnbG9iYWwgYm90dG9tIDUwJSBpbmNvbWUgc2hhcmUgcmVtYWlucyBoaXN0b3JpY2FsbHkgbG93IGRlc3BpdGUgZ3Jvd3RoIGluIHRoZSBlbWVyZ2luZyB3b3JsZCBpbiB0aGUgcGFzdCBkZWNhZGVzLiIsIHdpZHRoID0gMzApLCBzaXplID0gMykKYGBgCioqSW50ZXJwcmV0YXRpb24qKi4gVGhlIHNoYXJlIG9mIGdsb2JhbCBpbmNvbWUgZ29pbmcgdG8gdG9wIDEwJSBoaWdoZXN0IGluY29tZXMgYXQgdGhlIHdvcmxkIGxldmVsIGhhcyBmbHVjdHVhdGVkIGFyb3VuZCA1MC02MCUgYmV0d2VlbiAxODIwIGFuZCAyMDIwICg1MCUgaW4gMTgyMCwgNjAlIGluIDE5MTAsIDU2JSBpbiAxOTgwLCA2MSUgaW4gMjAwMCwgNTUlIGluIDIwMjApLCB3aGlsZSB0aGUgc2hhcmUgZ29pbmcgdG8gdGhlIGJvdHRvbSA1MCUgbG93ZXN0IGluY29tZXMgaGFzIGdlbmVyYWxseSBiZWVuIGFyb3VuZCBvciBiZWxvdyAxMCUgKDE0JSBpbiAxODIwLCA3JSBpbiAxOTEwLCA1JSBpbiAxOTgwLCA2JSBpbiAyMDAwLCA3JSBpbiAyMDIwKS4gR2xvYmFsIGluZXF1YWxpdHkgaGFzIGFsd2F5cyBiZWVuIHZlcnkgbGFyZ2UuIEl0IHJvc2UgYmV0d2VlbiAxODIwIGFuZCAxOTEwIGFuZCBzaG93cyBsaXR0bGUgbG9uZy1ydW4gdHJlbmQgYmV0d2VlbiAxOTEwIGFuZCAyMDIwLiBEaXN0cmlidXRpb24gb2YgcGVyIGNhcGl0YSBpbmNvbWVzLiBTb3VyY2VzIGFuZCBzZXJpZXM6IHNlZSB3aXIyMDIyLndpZC53b3JsZC9tZXRob2RvbG9neSBhbmQgQ2hhbmNlbCBhbmQgUGlrZXR0eSAoMjAyMSkuCgojIyMgRjg6IFRoZSByaXNlIG9mIHByaXZhdGUgdmVyc3VzIHRoZSBkZWNsaW5lIG9mIHB1YmxpYyB3ZWFsdGggaW4gcmljaCBjb3VudHJpZXMsIDE5NzAtMjAyMAoKYGBge3IgZGF0YS1mOCwgY2FzaCA9IFRSVUV9CmRmX2Y4IDwtIHJlYWRfZXhjZWwoImRhdGEvV0lSMjAyMlRhYmxlc0ZpZ3VyZXMtU3VtbWFyeS54bHN4Iiwgc2hlZXQgPSAiZGF0YS1GOCIpCmRmX2Y4CmBgYApgYGB7cn0KZGZfZjggJT4lIAogIHBpdm90X2xvbmdlcigheWVhciwgbmFtZXNfdG8gPSAiZ3JvdXAiLCB2YWx1ZXNfdG8gPSAidmFsdWUiKSAlPiUKICBnZ3Bsb3QoKSArCiAgc3RhdF9zbW9vdGgoYWVzKHggPSB5ZWFyLCB5ID0gdmFsdWUsIGNvbG9yID0gZ3JvdXApLCBzcGFuID0gMC4yNSwgc2UgPSBGQUxTRSwgc2l6ZT0wLjc1KSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKwogIGxhYnModGl0bGUgPSAiRmlndXJlIDguIFRoZSByaXNlIG9mIHByaXZhdGUgdmVyc3VzIHRoZSBkZWNsaW5lIG9mIHB1YmxpYyB3ZWFsdGggaW4gcmljaCBjb3VudHJpZXMsIDE5NzAtMjAyMCIsIAogICAgICAgeCA9ICIiLCB5ID0gIndlYWx0aCBhcyBhcyAlIG9mIG5hdGlvbmFsIGluY29tZSIsIGNvbG9yID0gIiIpCmBgYAoqKkludGVycHJldGF0aW9uKio6IFB1YmxpYyB3ZWFsdGggaXMgdGhlIHN1bSBvZiBhbGwgZmluYW5jaWFsIGFuZCBub24tZmluYW5jaWFsIGFzc2V0cywgbmV0IG9mIGRlYnRzLCBoZWxkIGJ5IGdvdmVybm1lbnRzLiBQdWJsaWMgd2VhbHRoIGRyb3BwZWQgZnJvbSA2MCUgb2YgbmF0aW9uYWwgaW5jb21lIGluIDE5NzAgdG8gLTEwNiUgaW4gMjAyMCBpbiB0aGUgVUsuICAgKipTb3VyY2VzIGFuZCBzZXJpZXMqKjogd2lyMjAyMi53aWQud29ybGQvbWV0aG9kb2xvZ3ksIEJhdWx1eiBldCBhbC4gKDIwMjEpIGFuZCB1cGRhdGVzLgoKCgojIyMgRjk6IEF2ZXJhZ2UgYW5udWFsIHdlYWx0aCBncm93dGggcmF0ZSwgMTk5NS0yMDIxCgpgYGB7ciBkYXRhLWY5LCBjYXNoID0gVFJVRX0KZGZfZjkgPC0gcmVhZF9leGNlbCgiZGF0YS9XSVIyMDIyVGFibGVzRmlndXJlcy1TdW1tYXJ5Lnhsc3giLCBzaGVldCA9ICJkYXRhLUY5IikKZGZfZjkKYGBgCmBgYHtyfQpkZl9mOSAlPiUgc2VsZWN0KHAsIHdlYWx0aCA9ICdXZWFsdGggZ3Jvd3RoIDE5OTUtMjAyMScpICU+JQogIGdncGxvdCgpICsKICBzdGF0X3Ntb290aChhZXMoeCA9IHAsIHkgPSB3ZWFsdGgpLCBzcGFuID0gMC4yNSwgc2UgPSBGQUxTRSkgKwojICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gcm91bmQoYyhzZXEoMCwgOTAsIGJ5ID0gMTApLCA5OS45LCA5OS45OSwgOTkuOTk5LDMpKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBsYWJzKHRpdGxlID0gIkZpZ3VyZSA5LiBBdmVyYWdlIGFubnVhbCB3ZWFsdGggZ3Jvd3RoIHJhdGUsIDE5OTUtMjAyMSIsIAogICAgICAgeCA9ICLihpAxJSBwb29yZXN0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdsb2JhbCB3ZWFsdGggZ3JvdXAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLjAwMSUgcmljaGVzdOKGkiIsIHkgPSAiUGVyIGFkdWx0IGFubnVhbCBncm93dGggcmF0ZSBpbiB3ZWFsdGgsIG5ldCBvZiBpbmZsYXRpb24gKCUpIiwgY29sb3IgPSAiIikKYGBgCioqSW50ZXJwcmV0YXRpb24qKjogR3Jvd3RoIHJhdGVzIGFtb25nIHRoZSBwb29yZXN0IGhhbGYgb2YgdGhlIHBvcHVsYXRpb24gd2VyZSBiZXR3ZWVuIDMlIGFuZCA0JSBwZXIgeWVhciwgYmV0d2VlbiAxOTk1IGFuZCAyMDIxLiBTaW5jZSB0aGlzIGdyb3VwIHN0YXJ0ZWQgZnJvbSB2ZXJ5IGxvdyB3ZWFsdGggbGV2ZWxzLCBpdHMgYWJzb2x1dGUgbGV2ZWxzIG9mIGdyb3d0aCByZW1haW5lZCB2ZXJ5IGxvdy4gVGhlIHBvb3Jlc3QgaGFsZiBvZiB0aGUgd29ybGQgcG9wdWxhdGlvbiBvbmx5IGNhcHR1cmVkIDIuMyUgb2Ygb3ZlcmFsbCB3ZWFsdGggZ3Jvd3RoIHNpbmNlIDE5OTUuIFRoZSB0b3AgMSUgIGJlbmVmaXRlZCBmcm9tIGhpZ2ggZ3Jvd3RoIHJhdGVzICgzJSB0byA5JSBwZXIgeWVhcikuIFRoaXMgZ3JvdXAgY2FwdHVyZWQgMzglIG9mIHRvdGFsIHdlYWx0aCBncm93dGggYmV0d2VlbiAxOTk1IGFuZCAyMDIxLiBOZXQgaG91c2Vob2xkIHdlYWx0aCBpcyBlcXVhbCB0byB0aGUgc3VtIG9mIGZpbmFuY2lhbCBhc3NldHMgKGUuZy4gZXF1aXR5IG9yIGJvbmRzKSBhbmQgbm9uLWZpbmFuY2lhbCBhc3NldHMgKGUuZy4gaG91c2luZyBvciBsYW5kKSBvd25lZCBieSBpbmRpdmlkdWFscywgbmV0IG9mIHRoZWlyIGRlYnRzLiAgIAoqKlNvdXJjZXMgYW5kIHNlcmllcyoqOiB3aXIyMDIyLndpZC53b3JsZC9tZXRob2RvbG9neS4KCiMjIyBGMTA6IFRoZSBzaGFyZSBvZiB3ZWFsdGggb3duZWQgYnkgdGhlIGdsb2JhbCAwLjElIGFuZCBiaWxsaW9uYWlyZXMsIDIwMjEKCmBgYHtyIGRhdGEtZjEwLCBjYXNoID0gVFJVRX0KZGZfZjEwIDwtIHJlYWRfZXhjZWwoImRhdGEvV0lSMjAyMlRhYmxlc0ZpZ3VyZXMtU3VtbWFyeS54bHN4Iiwgc2hlZXQgPSAiZGF0YS1GMTAiKQpkZl9mMTAKYGBgCgpgYGB7cn0KZGZfZjEwICU+JSAKICBzZWxlY3QoeWVhciwgIkdsb2JhbCBCaWxsaW9uYWlyZSBXZWFsdGgiID0gYm5faGh3ZWFsLCAiVG9wIDAuMDElIiA9IHRvcDAuMV9oaHdlYWwpICU+JQogIHBpdm90X2xvbmdlcigheWVhciwgbmFtZXNfdG8gPSAiZ3JvdXAiLCIudmFsdWUiLCB2YWx1ZXNfdG8gPSAidmFsdWUiKSAlPiUKICBnZ3Bsb3QoKSArCiAgc3RhdF9zbW9vdGgoYWVzKHggPSB5ZWFyLCB5ID0gdmFsdWUsIGNvbG9yID0gZ3JvdXApLCBzcGFuID0gMC4yNSwgc2UgPSBGQUxTRSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSByb3VuZChzZXEoMTk5NSwgMjAyMCwgYnkgPSA1KSwxKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPXJldihzY2FsZXM6Omh1ZV9wYWwoKSgyKSkpICsKICBsYWJzKHRpdGxlID0gIkZpZ3VyZSAxMC4gRXh0cmVtZSB3ZWFsdGggaW5lcXVhbGl0eTogXG50aGUgcmlzZSBvZiBnbG9iYWwgYmlsbGlvbmFpcmVzIGFuZCB0b3AgMC4wMSUsIDE5OTUtMjAyMSIsIAogICAgICAgeCA9ICIiLCB5ID0gIlNoYXJlIG9mIHRvdGFsIGhvdXNlaG9sZCB3ZWFsdGggKCUpIiwgY29sb3IgPSAiIikKYGBgCioqSW50ZXJwcmV0YXRpb24qKjogVGhlIHNoYXJlIG9mIHdlYWx0aCBkZXRhaW5lZCBieSB0aGUgd29ybGQncyBiaWxsaW9uYWlyZXMgcm9zZSBmcm9tIDElIG9mIHRvdGFsIGhvdXNlaG9sZCB3ZWFsdGggaW4gMTk5NSB0byBuZWFybHkgMy41JSB0b2RheS4gVGhlIHRocmVzaG9sZCBvZiB0b3AgMC4wMSUsIGNvbXBvc2VkIG9mIDUyMCAwMDAgYWR1bHRzLCBncmV3IGZyb20g4oKsNjkzLDAwMCAoUFBQKSBpbiAxOTk1IHRvIOKCrDE2LDY2NiwwMDAgdG9kYXkuIFRoZSBuZXQgaG91c2Vob2xkIHdlYWx0aCBpcyBlcXVhbCB0byB0aGUgc3VtIG9mIGZpbmFuY2lhbCBhc3NldHMgKGUuZy4gZXF1aXR5IG9yIGJvbmRzKSBhbmQgbm9uLWZpbmFuY2lhbCBhc3NldHMgKGUuZy4gaG91c2luZyBvciBsYW5kKSBvd25lZCBieSBpbmRpdmlkdWFscywgbmV0IG9mIHRoZWlyIGRlYnRzLiAgIAoqKlNvdXJjZXMgYW5kIHNlcmllcyoqOiB3aXIyMDIyLndpZC53b3JsZC9tZXRob2RvbG9neSwgQmF1bHV6IGV0IGFsLiAoMjAyMSkgYW5kIHVwZGF0ZXMuCgoKIyMjIEYxMTogVG9wIDElIHZzIGJvdHRvbSA1MCUgd2VhbHRoIHNoYXJlcyBpbiBXZXN0ZXJuIEV1cm9wZSBhbmQgdGhlIFVTLCAxOTEwLTIwMjAKCmBgYHtyIGRhdGEtZjExLCBjYXNoID0gVFJVRX0KZGZfZjExIDwtIHJlYWRfZXhjZWwoImRhdGEvV0lSMjAyMlRhYmxlc0ZpZ3VyZXMtU3VtbWFyeS54bHN4Iiwgc2hlZXQgPSAiZGF0YS1GMTEiKQpkZl9mMTEKYGBgCgpgYGB7cn0KZGZfZjExICU+JSAKICByZW5hbWUoIXllYXIsIFVTX2JvdDUwID0gVVNib3Q1MCwgVVNfdG9wMSA9IFVTdG9wMSwgRVVfYm90NTAgPSBFVWJvdDUwLCBFVV90b3AxID0gRVV0b3AxKSAlPiUKICBwaXZvdF9sb25nZXIoIXllYXIsIG5hbWVzX3RvID0gYygiZ3JvdXAiLCIudmFsdWUiKSwgbmFtZXNfc2VwID0gIl8iKSAlPiUKICBnZ3Bsb3QoKSArCiAgc3RhdF9zbW9vdGgoYWVzKHggPSB5ZWFyLCB5ID0gdG9wMSwgY29sb3IgPSBncm91cCksIHNwYW4gPSAwLjI1LCBzZSA9IEZBTFNFKSArCiAgc3RhdF9zbW9vdGgoYWVzKHggPSB5ZWFyLCB5ID0gYm90NTAsIGNvbG9yID0gZ3JvdXApLCBzcGFuID0gMC4yNSwgc2UgPSBGQUxTRSwgbGluZXR5cGUgPSAyKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHJvdW5kKHNlcSgxOTEwLCAyMDIwLCBieSA9IDEwKSwxKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBsYWJzKHRpdGxlID0gIkZpZ3VyZSAxMS4gVG9wIDElIHZzIGJvdHRvbSA1MCUgd2VhbHRoIHNoYXJlcyBcbiBpbiBXZXN0ZXJuIEV1cm9wZSBhbmQgdGhlIFVTLCAxOTEwLTIwMjAiLCAKICAgICAgIHggPSAiIiwgeSA9ICJTaGFyZSBvZiB0b3RhbCBwZXJzb25hbCB3ZWFsdGggKCUpIiwgY29sb3IgPSAiIikgKwogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDIwMDAsIHkgPSAwLjUwLCBsYWJlbCA9IHN0cmluZ3I6OnN0cl93cmFwKCJXZWFsdGggaW5lcXVhbGl0eSBoYXMgYmVlbiByaXNpbmcgYXQgZGlmZmVyZW50IHNwZWVkcyBhZnRlciBhIGhpc3RvcmljYWwgZGVjbGluZS4gVGhlIGJvdHRvbSA1MCUgaGFzIGFsd2F5cyBiZWVuIGV4dHJlbWVseSBsb3cuIiwgd2lkdGggPSAzMCksIHNpemUgPSAzKQpgYGAKKipJbnRlcnByZXRhdGlvbioqOiBUaGUgZ3JhcGggcHJlc2VudHMgZGVjZW5uYWwgYXZlcmFnZXMgb2YgdG9wIDElIHBlcnNvbmFsIHdlYWx0aCBzaGFyZXMgaW4gV2VzdGVybiBFdXJvcGUgYW5kIHRoZSBVUy4gQmV0d2VlbiAxOTEwIGFuZCAyMDIwLCB0aGUgdG9wIDElIHdhcyA1NSUgb24gYXZlcmFnZSBpbiBFdXJvcGUgdnMuIDQzJSBpbiB0aGUgVVMuIEEgY2VudHVyeSBsYXRlciwgdGhlIFVTIGlzIGFsbW9zdCBiYWNrIHRvIGl0cyBlYXJseSAyMHRoIGNlbnR1cnkgbGV2ZWwuIFNvdXJjZXMgYW5kIHNlcmllczogd2lyMjAyMi53aWQud29ybGQvbWV0aG9kb2xvZ3kuCgpgYGB7cn0KZGZfZjExICU+JSAKICByZW5hbWUoIXllYXIsIFVTX2JvdDUwID0gVVNib3Q1MCwgVVNfdG9wMSA9IFVTdG9wMSwgRVVfYm90NTAgPSBFVWJvdDUwLCBFVV90b3AxID0gRVV0b3AxKSAlPiUKICBwaXZvdF9sb25nZXIoIXllYXIsIG5hbWVzX3RvID0gYygiZ3JvdXAiLCIudmFsdWUiKSwgbmFtZXNfc2VwID0gIl8iKSAlPiUKICBwaXZvdF9sb25nZXIoMzo0LCBuYW1lc190byA9ICJ0eXBlIiwgdmFsdWVzX3RvID0gInZhbHVlIikgJT4lCiAgZ2dwbG90KCkgKwogIHN0YXRfc21vb3RoKGFlcyh4ID0geWVhciwgeSA9IHZhbHVlLCBjb2xvciA9IGdyb3VwLCBsaW5ldHlwZSA9IHR5cGUpLCBzcGFuID0gMC4yNSwgc2UgPSBGQUxTRSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSByb3VuZChzZXEoMTkxMCwgMjAyMCwgYnkgPSAxMCksMSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgbGFicyh0aXRsZSA9ICJGaWd1cmUgMTEuIFRvcCAxJSB2cyBib3R0b20gNTAlIHdlYWx0aCBzaGFyZXMgXG4gaW4gV2VzdGVybiBFdXJvcGUgYW5kIHRoZSBVUywgMTkxMC0yMDIwIiwgCiAgICAgICB4ID0gIiIsIHkgPSAiU2hhcmUgb2YgdG90YWwgcGVyc29uYWwgd2VhbHRoICglKSIsIGNvbG9yID0gIiIsIGxpbmV0eXBlID0gIiIpICsKICBhbm5vdGF0ZSgidGV4dCIsIHggPSAyMDAwLCB5ID0gMC41MCwgbGFiZWwgPSBzdHJpbmdyOjpzdHJfd3JhcCgiV2VhbHRoIGluZXF1YWxpdHkgaGFzIGJlZW4gcmlzaW5nIGF0IGRpZmZlcmVudCBzcGVlZHMgYWZ0ZXIgYSBoaXN0b3JpY2FsIGRlY2xpbmUuIFRoZSBib3R0b20gNTAlIGhhcyBhbHdheXMgYmVlbiBleHRyZW1lbHkgbG93LiIsIHdpZHRoID0gMzApLCBzaXplID0gMykKYGBgCmBgYHtyfQpkZl9mMTEgJT4lIAogIHJlbmFtZSgheWVhciwgVVNfYm90NTAgPSBVU2JvdDUwLCBVU190b3AxID0gVVN0b3AxLCBFVV9ib3Q1MCA9IEVVYm90NTAsIEVVX3RvcDEgPSBFVXRvcDEpICU+JQogIHBpdm90X2xvbmdlcigheWVhciwgbmFtZXNfdG8gPSBjKCJncm91cCIsIi52YWx1ZSIpLCBuYW1lc19zZXAgPSAiXyIpICU+JQogIHBpdm90X2xvbmdlcigzOjQsIG5hbWVzX3RvID0gInR5cGUiLCB2YWx1ZXNfdG8gPSAidmFsdWUiKSAlPiUKICBnZ3Bsb3QoKSArCiAgc3RhdF9zbW9vdGgoYWVzKHggPSB5ZWFyLCB5ID0gdmFsdWUsIGNvbG9yID0gZ3JvdXAsIGxpbmV0eXBlID0gdHlwZSksIHNwYW4gPSAwLjI1LCBzZSA9IEZBTFNFKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHJvdW5kKHNlcSgxOTEwLCAyMDIwLCBieSA9IDEwKSwxKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBsYWJzKHRpdGxlID0gIkZpZ3VyZSAxMS4gVG9wIDElIHZzIGJvdHRvbSA1MCUgd2VhbHRoIHNoYXJlcyBcbiBpbiBXZXN0ZXJuIEV1cm9wZSBhbmQgdGhlIFVTLCAxOTEwLTIwMjAiLCAKICAgICAgIHggPSAiIiwgeSA9ICJTaGFyZSBvZiB0b3RhbCBwZXJzb25hbCB3ZWFsdGggKCUpIiwgY29sb3IgPSAiIiwgbGluZXR5cGUgPSAiIikgKwogIHNjYWxlX2xpbmV0eXBlX21hbnVhbCh2YWx1ZXMgPSBjKCJkb3R0ZWQiLCJzb2xpZCIpKSArCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gMjAwMCwgeSA9IDAuNTAsIGxhYmVsID0gc3RyaW5ncjo6c3RyX3dyYXAoIldlYWx0aCBpbmVxdWFsaXR5IGhhcyBiZWVuIHJpc2luZyBhdCBkaWZmZXJlbnQgc3BlZWRzIGFmdGVyIGEgaGlzdG9yaWNhbCBkZWNsaW5lLiBUaGUgYm90dG9tIDUwJSBoYXMgYWx3YXlzIGJlZW4gZXh0cmVtZWx5IGxvdy4iLCB3aWR0aCA9IDMwKSwgc2l6ZSA9IDMpCmBgYAoKIyMjIEYxMjogRmVtYWxlIHNoYXJlIGluIGdsb2JhbCBsYWJvciBpbmNvbWVzLCAxOTkwLTIwMjAKCmBgYHtyIGRhdGEtZjEyLCBjYXNoID0gVFJVRX0KZGZfZjEyIDwtIHJlYWRfZXhjZWwoImRhdGEvV0lSMjAyMlRhYmxlc0ZpZ3VyZXMtU3VtbWFyeS54bHN4Iiwgc2hlZXQgPSAiZGF0YS1GMTIiKQpkZl9mMTIKYGBgCgpgYGB7cn0KZGZfZjEyICU+JSAKICBzZWxlY3QoeWVhciA9ICJEYXRhIG5lZWRzIHRvIGJlIHVwZGF0ZWQiLCB2YWx1ZSA9IC4uLjIpICU+JQogIGZpbHRlcighaXMubmEoeWVhcikpICU+JQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSB2YWx1ZSkpICsKICBnZW9tX2NvbCh3aWR0aCA9IDAuNSwgZmlsbCA9ICJibHVlIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuNSwgbGluZXR5cGUgPSAyLCBjb2xvdXIgPSAicmVkIikgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBsYWJzKHRpdGxlID0gIkZpZ3VyZSAxMi4gRmVtYWxlIHNoYXJlIGluIGdsb2JhbCBsYWJvciBpbmNvbWVzLCAxOTkwLTIwMjAiLCAKICAgICAgICB4ID0gIiIsIHkgPSAiIikgKwogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDEsIHkgPSAwLjQ4LCBsYWJlbCA9ICJHZW5kZXIgcGFyaXR5Iiwgc2l6ZSA9IDMpICsKICBhbm5vdGF0ZSgidGV4dCIsIHggPSA1LjIsIHkgPSAwLjQ3LCBsYWJlbCA9IHN0cmluZ3I6OnN0cl93cmFwKCJXb21lbiBtYWtlIG9ubHkgMzUlIG9mIGdsb2JhbCBsYWJvciBpbmNvbWVzLCBtZW4gbWFrZSB0aGUgcmVtYWluaW5nICA2NSUuIiwgd2lkdGggPSA0MCksIHNpemUgPSAzKQpgYGAKKipJbnRlcnByZXRhdGlvbioqOiBUaGUgc2hhcmUgb2YgZmVtYWxlIGluY29tZXMgaW4gZ2xvYmFsIGxhYm91ciBpbmNvbWVzIHdhcyAzMSUgaW4gMTk5MCBhbmQgbmVhcnMgMzUlIGluIDIwMTUtMjAyMC4gVG9kYXksIG1hbGVzIG1ha2UgdXAgNjUlIG9mIHRvdGFsIGxhYm9yIGluY29tZXMuIFNvdXJjZXMgYW5kIHNlcmllczogd2lyMjAyMi53aWQud29ybGQvbWV0aG9kb2xvZ3kgYW5kIE5lZWYgYW5kIFJvYmlsbGlhcmQgKDIwMjEpLgoKCiMjIyBGMTM6IEZlbWFsZSBsYWJvciBpbmNvbWUgc2hhcmUgYWNyb3NzIHRoZSB3b3JsZCwgMTk5MC0yMDIwCgpOb3RlIHRoYXQgdGhlIHNoZWV0IG5hbWUgb2YgRjEzIGhhcyBwZXJpb2QgYXQgdGhlIGVuZC4gTm90ZSB0aGF0IGBzdW1tYXJ5X3NoZWV0c1szMF0gPSBgYHIgc3VtbWFyeV9zaGVldHNbMzBdYCB3aXRoIGEgcGVyaW9kLgoKYGBge3IgZGF0YS1mMTMsIGNhc2ggPSBUUlVFfQpkZl9mMTMgPC0gcmVhZF9leGNlbCgiZGF0YS9XSVIyMDIyVGFibGVzRmlndXJlcy1TdW1tYXJ5Lnhsc3giLCBzaGVldCA9ICJkYXRhLUYxMy4iKQpkZl9mMTMKYGBgCgpgYGB7cn0KZGZfZjEzICU+JSBwaXZvdF9sb25nZXIoMjo5LCBuYW1lc190byA9ICJyZWdpb24iLCB2YWx1ZXNfdG8gPSAidmFsdWUiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSByZWdpb24sIHkgPSB2YWx1ZSwgZmlsbCA9IC4uLjEpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuNSwgbGluZXR5cGUgPSAyLCBjb2xvdXIgPSAicmVkIikgKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gZnVuY3Rpb24oeCkgc3RyaW5ncjo6c3RyX3dyYXAoeCwgd2lkdGggPSAxMikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgbGFicyh0aXRsZSA9ICJGaWd1cmUgMTMuIEZlbWFsZSBsYWJvciBpbmNvbWUgc2hhcmUgYWNyb3NzIHRoZSB3b3JsZCwgMTk5MC0yMDIwIiwgCiAgICAgICAgeCA9ICIiLCB5ID0gIiIsIGZpbGwgPSAiIikgKwogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDEuMiwgeSA9IDAuNDgsIGxhYmVsID0gIkdlbmRlciBwYXJpdHkiLCBzaXplID0gMykKYGBgCioqSW50ZXJwcmV0YXRpb24qKjogVGhlIGZlbWFsZSBsYWJvdXIgaW5jb21lIHNoYXJlIHJvc2UgZnJvbSAzNCUgdG8gMzglIGluIE5vcnRoIEFtZXJpY2EgYmV0d2VlbiAxOTkwIGFuZCAyMDIwLiBTb3VyY2VzIGFuZCBzZXJpZXM6IHdpcjIwMjIud2lkLndvcmxkL21ldGhvZG9sb2d5IGFuZCBOZWVmIGFuZCBSb2JpbGxpYXJkICgyMDIxKS4KCiMjIyBGMTQ6IEdsb2JhbCBjYXJib24gaW5lcXVhbGl0eSwgMjAxOS4gR3JvdXAgY29udHJpYnV0aW9uIHRvIHdvcmxkIGVtaXNzaW9ucyAoJSkKCk5vdGUgdGhhdCB0aGUgc2hlZXQgbmFtZSBvZiBGMTQgaGFzIHBlcmlvZCBhdCB0aGUgZW5kLiBOb3RlIHRoYXQgYHN1bW1hcnlfc2hlZXRzWzMxXSA9IGBgciBzdW1tYXJ5X3NoZWV0c1szMV1gIHdpdGggYSBwZXJpb2QuCgpgYGB7ciBkYXRhLWYxNCwgY2FzaCA9IFRSVUV9CmRmX2YxNCA8LSByZWFkX2V4Y2VsKCJkYXRhL1dJUjIwMjJUYWJsZXNGaWd1cmVzLVN1bW1hcnkueGxzeCIsIHNoZWV0ID0gImRhdGEtRjE0LiIpCmRmX2YxNApgYGAKCiogYFxuYCBmb3IgbGluZSBicmVhayBpbiB0aGUgdGl0bGUuCgpgYGB7cn0KZGZfZjE0ICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBHcm91cCwgeSA9IFNoYXJlKSkgKwogIGdlb21fY29sKHdpZHRoID0gMC41LCBmaWxsID0gImJsdWUiKSArIAogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBsYWJzKHRpdGxlID0gIkZpZ3VyZSAxNC4gR2xvYmFsIGNhcmJvbiBpbmVxdWFsaXR5LCBcbjIwMTkgR3JvdXAgY29udHJpYnV0aW9uIHRvIHdvcmxkIGVtaXNzaW9ucyAoJSkiLCAKICAgICAgIHggPSAiIiwgeSA9ICJTaGFyZSBvZiB3b3JsZCBlbWlzc2lvbnMgKCUpIikKYGBgCgoqKkludGVycHJldGF0aW9uKio6IFBlcnNvbmFsIGNhcmJvbiBmb290cHJpbnRzIGluY2x1ZGUgZW1pc3Npb25zIGZyb20gZG9tZXN0aWMgY29uc3VtcHRpb24sIHB1YmxpYyBhbmQgcHJpdmF0ZSBpbnZlc3RtZW50cyBhcyB3ZWxsIGFzIGltcG9ydHMgYW5kIGV4cG9ydHMgb2YgY2FyYm9uIGVtYmVkZGVkIGluIGdvb2RzIGFuZCBzZXJ2aWNlcyB0cmFkZWQgd2l0aCB0aGUgcmVzdCBvZiB0aGUgd29ybGQuIE1vZGVsZWQgZXN0aW1hdGVzIGJhc2VkIG9uIHRoZSBzeXN0ZW1hdGljIGNvbWJpbmF0aW9uIG9mIHRheCBkYXRhLCBob3VzZWhvbGQgc3VydmV5cyBhbmQgaW5wdXQtb3V0cHV0IHRhYmxlcy4gRW1pc3Npb25zIHNwbGl0IGVxdWFsbHkgd2l0aGluIGhvdXNlaG9sZHMuIFNvdXJjZXMgYW5kIHNlcmllczogd2lyMjAyMi53aWQud29ybGQvbWV0aG9kb2xvZ3kgYW5kIENoYW5jZWwgKDIwMjEpLgoKIyMjIEYxNTogUGVyIGNhcGl0YSBlbWlzc2lvbnMgYWNyaXNzIHRoZSB3b3JsZCwgMjAxOQoKYGBge3IgZGF0YS1mMTUsIGNhc2ggPSBUUlVFfQpkZl9mMTUgPC0gcmVhZF9leGNlbCgiZGF0YS9XSVIyMDIyVGFibGVzRmlndXJlcy1TdW1tYXJ5Lnhsc3giLCBzaGVldCA9ICJkYXRhLUYxNSIpCmRmX2YxNQpgYGAKYGBge3J9CmRmX2YxNSAlPiUgbXV0YXRlKHJlZ2lvbiA9IHJlcChyZWdpb25XSURbIWlzLm5hKHJlZ2lvbldJRCldLCBlYWNoID0gMykpICU+JQogIHNlbGVjdChyZWdpb24sIGdyb3VwLCB0Y2FwKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSByZWdpb24sIHkgPSB0Y2FwLCBmaWxsID0gZ3JvdXApKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArIAogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gZnVuY3Rpb24oeCkgc3RyaW5ncjo6c3RyX3dyYXAoeCwgd2lkdGggPSAxMCkpICsKICBsYWJzKHRpdGxlID0gIkZpZ3VyZSAxNSBQZXIgY2FwaXRhIGVtaXNzaW9ucyBhY3Jvc3MgdGhlIHdvcmxkLCAyMDE5IiwgCiAgICAgICB4ID0gIiIsIHkgPSAidG9ubmVzIG9mIENPMmUgcGVyIHBlcnNvbiBwZXIgeWVhciIsIGZpbGwgPSAiIikKYGBgCioqSW50ZXJwcmV0YXRpb24qKjogUGVyc29uYWwgY2FyYm9uIGZvb3RwcmludHMgaW5jbHVkZSBlbWlzc2lvbnMgZnJvbSBkb21lc3RpYyBjb25zdW1wdGlvbiwgcHVibGljIGFuZCBwcml2YXRlIGludmVzdG1lbnRzIGFzIHdlbGwgYXMgaW1wb3J0cyBhbmQgZXhwb3J0cyBvZiBjYXJib24gZW1iZWRkZWQgaW4gZ29vZHMgYW5kIHNlcnZpY2VzIHRyYWRlZCB3aXRoIHRoZSByZXN0IG9mIHRoZSB3b3JsZC4gTW9kZWxlZCBlc3RpbWF0ZXMgYmFzZWQgb24gdGhlIHN5c3RlbWF0aWMgY29tYmluYXRpb24gb2YgdGF4IGRhdGEsIGhvdXNlaG9sZCBzdXJ2ZXlzIGFuZCBpbnB1dC1vdXRwdXQgdGFibGVzLiBFbWlzc2lvbnMgc3BsaXQgZXF1YWxseSB3aXRoaW4gaG91c2Vob2xkcy4gU291cmNlcyBhbmQgc2VyaWVzOiB3aXIyMDIyLndpZC53b3JsZC9tZXRob2RvbG9neSBhbmQgQ2hhbmNlbCAoMjAyMSkuCgoKYGBge3J9CnJlZ2lvbl90ZXN0IDwtIHJlcChkZl9mMTUkcmVnaW9uV0lEWyFpcy5uYShkZl9mMTUkcmVnaW9uV0lEKV0sIGVhY2ggPSAzKQpyZWdpb25fdGVzdApgYGAKCgojIyMgVDEgR2xvYmFsIG1pbGxpb25haXJlcyBhbmQgYmlsbGlvbmFpcmVzLCAyMDIxCgpDaGVjayB0aGUgZm9ybWF0IG9mIHRoZSBzaGVldCBhbmQgYWRkIGBza2lwPTQsIG5fbWF4PTdgLgoKYGBge3IgVDF9CmRmX3QxIDwtIHJlYWRfZXhjZWwoImRhdGEvV0lSMjAyMlRhYmxlc0ZpZ3VyZXMtU3VtbWFyeS54bHN4IiwgCiAgICAgICAgICAgICAgICAgICAgc2hlZXQgPSAiVDEiLCBza2lwID0gNCwgbl9tYXggPSA3KQpkZl90MQpgYGAKKipJbnRlcnByZXRhdGlvbioqOiBJbiAyMDIxLCB0aGVyZSB3ZXJlIDYyLjIgbWlsbGlvbiBwZW9wbGUgaW4gdGhlIHdvcmxkIG93bmluZyBtb3JlIHRoYW4gJDEgbWlsbGlvbiAobWVhc3VyZWQgYXQgTWFya2V0IEV4Y2hhbmdlIFJhdGVzKS4gVGhlaXIgYXZlcmFnZSB3ZWFsdGggd2FzICQgMi44IG1pbGxpb24sIHJlcHJlc2VudGluZyBhIHRvdGFsIG9mICAkMTc0IHRyaWxsaW9uLiBJbiBvdXIgVGF4IHNjZW5hcmlvIDIsIGEgZ2xvYmFsIHByb2dyZXNzaXZlIHdlYWx0aCB0YXggd291bGQgeWllbGQgMi4xJSBvZiBnbG9iYWwgaW5jb21lLCB0YWtpbmcgaW50byBhY2NvdW50IGNhcGl0YWwgZGVwcmVjaWF0aW9uIGFuZCBldmFzaW9uLiBTb3VyY2VzIGFuZCBzZXJpZXM6IHdpcjIwMjIud2lkLndvcmxkL21ldGhvZG9sb2d5LgoK